#ifndef ENGINE_SCENEMANAGER_H
#define ENGINE_SCENEMANAGER_H

#include <string>
#include <memory>
#include <unordered_map>
#include <functional>
#include <stdexcept> // 包含 std::runtime_error
#include "Scene.h"   // 包含 Scene 类

namespace GameEngine {

    class SceneManager {
    public:
        SceneManager();
        ~SceneManager();

        // 通过模板注册场景类型
        template<typename T>
        void RegisterScene(const std::string& name) {
            static_assert(std::is_base_of<Scene, T>::value, "T 必须继承自 Scene");
            if (m_sceneFactories.find(name) != m_sceneFactories.end()) {
                // 处理重复注册的情况
            }
            // 使用 Lambda 表达式定义一个工厂函数
            // 当调用时，将创建一个 std::shared_ptr<T> 实例
            m_sceneFactories[name] = [this, name]() {
                auto scene = std::make_shared<T>(name);
                static_cast<Scene*>(scene.get())->m_sceneManager = this; // 设置场景管理器指针
                return scene;
                };
        }

        // 支持传递参数的注册场景方法
        template<typename T, typename... Args>
        void RegisterScene(const std::string& name, Args&&... args) {
            static_assert(std::is_base_of<Scene, T>::value, "T 必须继承自 Scene");
            if (m_sceneFactories.find(name) != m_sceneFactories.end()) {
                // 处理重复注册的情况
            }
            m_sceneFactories[name] = [this, name, args...]() {
                auto scene = std::make_shared<T>(name, std::forward<Args>(args)...);
                static_cast<Scene*>(scene.get())->m_sceneManager = this; // 设置场景管理器指针
                return scene;
                };
        }

        // 切换到指定名称的场景
        // 如果场景未加载，则进行加载和初始化
        void SwitchToScene(const std::string& name);

        // 更新当前活动场景
        void UpdateCurrentScene(float deltaTime);

        // 渲染当前活动场景
        void RenderCurrentScene();

        // 获取当前活动场景
        std::shared_ptr<Scene> GetCurrentScene() const;

        // 根据名称获取场景，如果未注册则创建
        std::shared_ptr<Scene> GetScene(const std::string& name);

        // 卸载指定名称的场景
        void UnloadScene(const std::string& name);

        // 卸载所有场景
        void UnloadAllScenes();

    private:
        // m_sceneFactories 存储场景名称到场景工厂函数的映射。
        std::unordered_map<std::string, std::function<std::shared_ptr<Scene>()>> m_sceneFactories;
        std::unordered_map<std::string, std::shared_ptr<Scene>> m_loadedScenes;
        std::shared_ptr<Scene> m_currentScene;
        std::string m_currentSceneName;
    };

}

#endif